“命令式” vs “声明式”? VMWare Project Pacific小探
点击蓝字关注,一起探讨更好玩的IT世界
上周跟VMware聊他们的新产品,被强调了多次“声明式”的优点,让我回想起了计算机编程语言中的种种分类,为了回忆我那许久不用的专业知识,周末我花了点时间复习了一下当年的功课,同时也研究了一下VMware的Project Pacific到底做了啥。
编程范式(Programming Paradigm)
按照Wikipedia上的定义,编程范式主要有两种,一种叫命令式(Imperative),主要定义机器执行过程,即指导机器改变状态,比如像C,Fortran或者Pascal这种面向过程的语言以及像C++,Java这种面向对象的语言。
还有一种叫做声明式(Declarative),主要是定义机器的最终状态而不是执行过程,包括三类:
函数式(Functional),结果定义为一系列函数的值。
逻辑式(Logic),结果定义为一系列事实或规则的结果。
数学(Mathematics), 结果定义为一系列优化问题的结果。
目前很多新的编程语言都支持多种编程范式,比如C#里的LINQ,Java 8 里的Lambda表达式,都是声明式的。早期还有一种语言叫LISP,是著名的函数式编程语言。
Wikipedia上有一张图我看得不是特别明白,来自比利时鲁汶大学(Catholic University of Louvain)教授Peter Van Roy的文章"Programming Paradigms: What Every Programmer Should Know",看上去是对编程语言更学术的分类,看着很深奥的样子,我就不仔细研究了。
在思考这个问题的时候,我下意识的反应是《圣经》里上帝的行为,一种是命令式的,一种是声明式的。
命令式:“神说,我们要照着我们的形像,按着我们的样式造人,使他们管理海里的鱼,空中的鸟,地上的牲畜,和全地,并地上所爬的一切昆虫。”
声明式:“神说,要有光,就有了光。”
好吧,回到正题。从代码的角度而言,声明式的代码看上去更结果导向一些,而命令式代码看上去更加繁杂一些。现在比较有经验的程序员可能更喜欢用声明式的方式来编写,让代码结构更清楚,犯错的概率变小,降低调试的成本。
我们来看一下C#里的两种代码风格:
C#命令式代码:
C#声明式代码:
Project Pacific具体做了什么?
凡事不自己摸一摸就没有发言权,对一些新的产品如果不去看看技术文档,就不能说自己知道是什么。毕竟这个行业新名词太多,一不当心就会跳坑里被忽悠。所以我又花了点时间去看了一下VMware Project Pacific的技术文档,有两张图的印象比较深刻,一张是这个:
这是把Kubernetes集成到了vSphere当中,可以直接在vSphere上运行容器,叫Native Pods,效率得到了提升,比Linux VM上快30%,比裸机上快8%。还可以直接用vSphere的管理界面起k8s的集群,把虚拟机和容器提升到了一个水平线上。
好吧,前几年在容器和OpenStack打架的时候VMware还闭口不谈容器,现在看上去是全面拥抱容器技术了。这个选择和大多数云厂商是一样的,真为OpenStack感到伤心。
另外一张我印象比较深刻图是这个:
中间部分是新时代应用的核心,下面部分画的是无服务器计算,即FaaS。上面部分是各种传统节点,控制平面和应用程序,节点上可以跑虚拟机或者容器,里面可能跑着数据库,也可能是一些旧应用。两边是基于Yaml格式的一些声明式定义,包括类型,元数据,版本等等。通过它我们可以用Yaml格式定义相关的资源,发布应用之后,vSphere会帮我们创建资源,最终统一管理。
这是典型的声明式的写法,当然类似的写法有很多,包括AWS CloudFormation基于Json格式写法,还有Microsoft Azure ARM。一些脚本语言用Yaml的会多一些。关于Yaml和Json的区别,网上资料很多,这里我就不多说了。
鉴于Project Pacific是对vSphere加了Kubernetes的支持,而且这个声明式的定义看着是标准的Yaml格式,所以我猜,VMware应该是基于Kubernetes 的自定义资源类型(Custom Resource Definition, CRD),扩展了VMware的资源,在统一的平面上支持了Pod和VM的管理和互相通讯。
Kubernetes的CRD可以扩展资源,通过Yaml进行声明,实现可以用golang,写完以后通过kubectl命令调用相关的REST API创建自定义资源,并进行CRUD操作。当然我以前也不知道k8s支持这个骚操作,所以又进一步去看了看github上的一个代码例子:
https://github.com/kubernetes/sample-controller
在这个例子里,演示了三件事:
在k8s里注册一个Foo类型的自定义资源(CRD)
创建Foo类型CRD的实例
通过资源上的控制器,操作创建、更新、删除事件。
写完代码以后,可以通过kubectl调用相关REST API创建自定义资源并部署:
具体的实现可以放在pkg目录下的register.go和types.go里,还有自动代码生成的工具,可以实现基本操作。
再看看Project Pacific,工具是一样的,都是kubectl,命令也大同小异。
做完之后,可以直接在vSphere里同时操作k8s集群,容器和虚拟机。支持安全集成,k8s的事件也可以统一收集上来一并展示。
所以Project Pacific通过定义k8s的CRD,用Yaml对资源进行了扩展,能够统一编排容器和虚拟机,提升了用户的体验。
所以想想,k8s也是挺牛的,可以让那么多厂商跟随它的脚步,基于它定义的标准,扩展商业软件产品。这在过去商业软件纵横天下的时代,是无法想象的。
END
曾今,伏案只识技术世界
而后,抬头遍历创业之艰
现如今
不惑之年
以创业者眼光,再探技术世界
长按二维码关注,一起窥探云上世界
🔻
关于作者
Hotcan,80后技术老炮儿
云计算和数字化技术的创业者
创业公司被收购之后,负责云和数字化转型业务
历史文章